<script setup lang="ts">
import { ref, reactive, toRefs } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus, ArrowRight, ArrowDown } from '@element-plus/icons-vue'
import TreeNode from './components/TreeNode.vue'
import TypeLabel from './components/TypeLabel.vue'
import TypeSettings from './components/TypeSettings.vue'
import { createField, canAddChildren, findParentNode } from './utils/nodeUtils'


const state = reactive({
  id: '',
  name: '',
  code: '',
  groupName: '',
  rootNode: {
    type: 'array',
    fieldDesc: '',
    properties: {},
    APIPOST_ORDERS: [],
    expanded: true,
  }
})

const {
  id, name, code, groupName, rootNode
} = toRefs(state)

const initModelData = function (data:any) {
  state.id = data.id
  state.name = data.name
  state.code = data.code
  state.groupName = data.groupName
  if (data.model && JSON.stringify(data.model) != '"{}"') {
    state.rootNode = JSON.parse(data.model)
    console.log('state.rootNode', state.rootNode);
  } else
    state.rootNode = {
      type: 'array',
      fieldDesc: '',
      properties: {},
      APIPOST_ORDERS: [],
      expanded: true,
    }
}

// 弹窗相关的响应式数据
const dialogVisible = ref(false)
const currentNode = ref(null)
const originalNode = ref(null)

// 展开/收起节点
const toggleExpand = (node) => {
  node.expanded = !node.expanded
}

// 添加子节点
const addChild = ({ node, parentNode }) => {
  if (!node || !parentNode) {
    node = rootNode.value;
    node.items = {};
  }
  if (!canAddChildren(node?.type, node)) {
    return;
  }
  
  if (parentNode?.type === 'array') {
    const newField = createField(node.type === 'array' ? 'object' : 'string')

    // 生成唯一的字段名
    let fieldName = `field_${Date.now()}`
    let index = 1
    while (parentNode?.items.properties[fieldName]) {
      fieldName = `field_${Date.now()}_${index++}`
    }
    newField.fieldName = fieldName

    // 确保父节点的必要属性存在
    if (!parentNode?.items.properties) {
      parentNode.items.properties = {}
    }
    if (!parentNode?.items.APIPOST_ORDERS) {
      parentNode.items.APIPOST_ORDERS = []
    }

    // 添加新字段
    node.properties[fieldName] = newField
    node.APIPOST_ORDERS.push(fieldName)
    node.expanded = true

    parentNode.items.properties[fieldName] = newField
    parentNode.items.APIPOST_ORDERS.push(fieldName)
    parentNode.items.expanded = true;
  } else {
    const newField = createField(node.type === 'array' ? 'object' : 'string')

    // 生成唯一的字段名
    let fieldName = `field_${Date.now()}`
    let index = 1
    while (node.properties[fieldName]) {
      fieldName = `field_${Date.now()}_${index++}`
    }
    newField.fieldName = fieldName

    // 确保父节点的必要属性存在
    if (!node.items?.properties) {
      node.items.properties = {}
    }
    if (!node.items?.APIPOST_ORDERS) {
      node.items.APIPOST_ORDERS = []
    }

    // 添加新字段
    node.properties[fieldName] = newField
    node.APIPOST_ORDERS.push(fieldName)
    node.items.properties[fieldName] = newField
    node.items.APIPOST_ORDERS.push(fieldName)
    node.expanded = true
  }
}

// 删除字段
const removeField = (node) => {
  const result = findParentNode(rootNode.value, node)
  if (result) {
    const { parent, fieldName } = result
    delete parent.properties[fieldName]
    const index = parent.APIPOST_ORDERS.indexOf(fieldName);
    if (index > -1) {
      parent.APIPOST_ORDERS.splice(index, 1)
    }
  }
}

// 显示类型设置
const showTypeSettings = (node) => {
  const isRoot = node === rootNode.value

  const result = isRoot ? null : findParentNode(rootNode.value, node)
  // currentNode.value = JSON.parse(JSON.stringify(node))
  // originalNode.value = JSON.parse(JSON.stringify(node))
  currentNode.value = node
  originalNode.value = node

  // 设置节点的引用关系
  currentNode.value._isRoot = isRoot
  if (!isRoot && result) {
    currentNode.value._parent = result.parent
    currentNode.value._fieldName = result.fieldName
  }
  dialogVisible.value = true
}

const changeNodePropName = (node: any) => {
  console.log(node)
  if (node && node.type == 'object') {
    var orderList = [];
    var properties = {};
    for (var i = 0; i < node.APIPOST_ORDERS.length; i++) {
      var element = node.APIPOST_ORDERS[i];
      console.log(element)
      var fieldName = node.properties[element].fieldName;
      if (!fieldName) {
        ElMessage.error('请填写字段名称!');
        return false;
      }
      var check = changeNodePropName(node.properties[element]);
      if (!check) {
        return false;
      }
      orderList.push(fieldName);
      properties[fieldName] = node.properties[element];
    }
    node.APIPOST_ORDERS = orderList;
    node.properties = properties;
  }

  if (node && node.type == 'array') {
    if (node.items) {
      return changeNodePropName(node.items)
    } else {
      return false;
    }
  }
  return true;
}

// 保存模型
const saveModel = () => {
  const stateClone = JSON.parse(JSON.stringify(state));
  console.log(stateClone.rootNode)
  const check = changeNodePropName(stateClone.rootNode)
  console.log(stateClone.rootNode)
  if (check) {
    emit('onSave', stateClone)
  }
}

// 保存设置
const handleSaveSettings = () => {
  if (currentNode.value) {
    const isRoot = currentNode.value._isRoot;
    const parent = currentNode.value._parent;
    const fieldName = currentNode.value._fieldName;

    // 创建一个新的对象来存储更新后的数据
    const updatedData = JSON.parse(JSON.stringify(currentNode.value));
    delete updatedData._isRoot;
    delete updatedData._parent;
    delete updatedData._fieldName;
    if (isRoot) {
      // 更新根节点
      Object.keys(updatedData).forEach(key => {
        rootNode.value[key] = updatedData[key];
      });
    } else if (parent && fieldName) {
      // 更新子节点
      const targetNode = parent.properties[fieldName];
      Object.keys(updatedData).forEach(key => {
        targetNode[key] = updatedData[key];
      });
    }

    // 强制更新视图
    if (parent) {
      parent.APIPOST_ORDERS = [...parent.APIPOST_ORDERS]
    }
  }

  dialogVisible.value = false;
  currentNode.value = null;
  originalNode.value = null;


}

// 弹窗关闭处理（取消时的处理）
const handleDialogClose = () => {
  if (currentNode.value && originalNode.value) {
    const isRoot = currentNode.value._isRoot;
    const parent = currentNode.value._parent;
    const fieldName = currentNode.value._fieldName;

    if (isRoot) {
      // 如果是根节点，恢复根节点的所有属性
      Object.keys(originalNode.value).forEach(key => {
        rootNode.value[key] = originalNode.value[key];
      });
    } else if (parent && fieldName) {
      // 如果是子节点，恢复对应的属性
      const targetNode = parent.properties[fieldName];
      Object.keys(originalNode.value).forEach(key => {
        targetNode[key] = originalNode.value[key];
      });
    }
  }
  dialogVisible.value = false;
  currentNode.value = null;
  originalNode.value = null;
}

const emit = defineEmits([
  'onSave'
])


defineExpose({
  initModelData
})
</script>



<template>
  <div class="data-model" v-if="id != ''">
    <div class="model-header">
      <div class="model-header-left">
        <h2 :title="'模型名称: ' + name">模型名称: {{ name }}</h2>
        <h2 :title="'模型编号: ' + code">模型编号: {{ code }}</h2>
      </div>
      <el-button type="primary" @click="saveModel">保存</el-button>
    </div>

    <!-- 树形结构区域 -->
    <div class="tree-container">
      <div class="root-node">
        <div class="node-content">
          <span class="expand-icon" @click.stop="toggleExpand(rootNode)">
            <el-icon>
              <ArrowRight v-if="!rootNode.expanded" />
              <ArrowDown v-else />
            </el-icon>
          </span>
          <span class="node-name">根节点</span>
          <TypeLabel :type="rootNode.type" @click="showTypeSettings(rootNode)" />
          <el-tooltip
            class="box-item"
            v-if="rootNode.fieldDesc"
            effect="dark"
            :content="rootNode.fieldDesc"
            placement="top"
          >
            <el-icon style="margin-right: 5px;"><InfoFilled /></el-icon>
          </el-tooltip>
          <el-button type="primary" link @click="addChild(rootNode)" v-if="canAddChildren(rootNode.type, rootNode)">
            <el-icon>
              <Plus />
            </el-icon>
          </el-button>
        </div>

        <!-- 子节点区域 -->
        <div class="children" v-if="rootNode.expanded">
          <TreeNode v-for="(child, index) in rootNode.APIPOST_ORDERS" :key="index" :node="rootNode.properties[child]"
            :parentNode="rootNode" @addChild="addChild" @removeField="removeField" :index="index" :list="rootNode.APIPOST_ORDERS"
            @showTypeSettings="showTypeSettings" />
        </div>
      </div>
    </div>

    <!-- 类型设置弹窗 -->
    <TypeSettings v-model:visible="dialogVisible" :node="currentNode" :original-node="originalNode"
      @save="handleSaveSettings" @close="handleDialogClose" />
  </div>
</template>



<style scoped lang="scss">
.data-model {
  height: 100%;
  display: flex;
  flex-direction: column;

  .model-header {
    padding: 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;

    &-left {
      flex: 1;
      overflow: hidden;

      h2 {
        font-size: 20px;
        margin: 0;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }
    }
  }

  .tree-container {
    flex: 1;
    padding: 16px;
    border: 1px solid #e4e7ed;
    border-radius: 4px;
    margin: 0 16px;
    overflow: auto;
  }

  .root-node {
    .node-content {
      display: flex;
      align-items: center;
      padding: 8px 0;

      .expand-icon {
        cursor: pointer;
        margin-right: 8px;
      }

      .node-name {
        margin-right: 16px;
      }
    }

    .children {
      margin-left: 24px;
      padding-left: 16px;
      border-left: 1px solid #dcdfe6;
    }
  }
}
</style>